/**
 Copyright (C) 2013 Yuyao Liang

 This source code is release under the BSD License.

 This program is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE.  See the license for more details.

 Created on Oct 29, 2013 1:02:11 PM
 */
package com.googlecode.backtest.rule.ta;

import java.util.ArrayList;
import java.util.List;

import com.google.srclib.data.DurationType;
import com.google.srclib.data.TAKeyName;
import com.googlecode.backtest.dataset.BackTestStockDataset;
import com.googlecode.backtest.dataset.IBackTestStockDataset;
import com.googlecode.backtest.dataset.manager.DataReadyEvent;
import com.googlecode.backtest.rule.ITAParameters;
import com.tictactec.ta.lib.MInteger;
import com.tictactec.ta.lib.RetCode;

/**
 * @author lianyuy
 * 
 */
public class WillR_Algorithm extends
		TABackTestAlgorithm<IBackTestStockDataset, ITAParameters> {

	private final String ID = getClass().getName();
	private final String VERSION = Messages
			.getString("WillR_Algorithm.VERSION"); //$NON-NLS-1$
	private final String Key = Messages.getString("WillR_Algorithm.key"); //$NON-NLS-1$
	private List<IBackTestStockDataset> dataset = new ArrayList<IBackTestStockDataset>();

	/**
	 * 
	 * @param id
	 * @param data_ids
	 */
	public WillR_Algorithm(String id, List<String> data_ids,
			ITAParameters parameter) {
		super(id, data_ids, parameter);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.google.srclib.base.IDable#getID()
	 */
	@Override
	public String getID() {
		return ID;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.google.srclib.base.Versionable#getVersion()
	 */
	@Override
	public String getVersion() {
		return VERSION;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.googlecode.backtest.rule.IBackTestAlgorithm#calculate(T[],
	 * java.lang.Object)
	 */
	@Override
	public boolean calculate(List<IBackTestStockDataset> dataset) {
		if (dataset.size() == 0) {
			return false;
		}

		IBackTestStockDataset ohlcdata = dataset.get(0);
		double[] highs = ohlcdata.getArray(TAKeyName.High.getKey());
		double[] lows = ohlcdata.getArray(TAKeyName.Low.getKey());
		double[] closes = ohlcdata.getArray(TAKeyName.Close.getKey());
		double[] out = new double[closes.length];
		MInteger begin = new MInteger();
		MInteger end = new MInteger();

		parameter.setSartIndex(parameter.getStartIndex() + 1);
		boolean ret = RetCode.Success == TAFactory.getTA().willR(
				parameter.getStartIndex(), parameter.getStopIndex(), highs,
				lows, closes, parameter.getParameter(), begin, end, out);
		if (ret) {
			BackTestStockDataset data = new BackTestStockDataset(
					DurationType.DAYS);
			result = (IBackTestStockDataset) dataset.get(0).cloneTo(data);
			int start = begin.value;
			int stop = end.value;
			for (int i = 0; i < closes.length; i++) {
				double value = Double.NaN;
				if (i < start || i > stop) {

				} else {
					value = out[i - start];
				}
				result.put(Key, value);
			}
		}

		manager.putData(this.getGUID(), result);
		return ret;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.googlecode.backtest.rule.IBackTestAlgorithm#getKey()
	 */
	@Override
	public String getKey() {
		return Key;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.googlecode.backtest.rule.ta.TABackTestAlgorithm#OnDataReady(com.
	 * googlecode.backtest.dataset.manager.DataReadyEvent)
	 */
	@Override
	public void OnDataReady(DataReadyEvent event) {
		super.OnDataReady(event);
		String key = event.getKey();
		int index = data_ids.indexOf(key);
		dataset.add(index,
				(IBackTestStockDataset) event.getManager().getData(key));

		if (calculate(dataset)) {
			System.out.println("Data ready!");
		}
	}

}
